package com.yn.sample.util;

/**
 * 增加不同枚举之间的跨度，方便增加新的状态
 */
public enum  ParseStateEnum {
    CONSTANT_POOL_STARTED(1,"常量池解析开始"),
    CONSTANT_POOL_END(5,"常量池解析结束"),

    METHOD_INFO_STARTED(10,"方法的常规信息区域，解析开始，比如描述符，flags等"),

    /**
     * java代码里，定义了一个静态常量field：
     * public static final int constantInt = 333;
     *
     * 然后在javap中，在常量池结束后，有如下一段：
     *   #43 = Utf8               java/lang/Object   ----------常量池结束
     * {
     *   public static final int constantInt;
     *     descriptor: I
     *     flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
     *     ConstantValue: int 333
     */
    CONSTANT_FIELD_INFO_STARTED(15,"静态常量的定义部分，比如一个static final变量等"),

    METHOD_CODE_STARTED(20,"方法的代码区域解析开始"),

    /**
     * 比如，对于方法：  public com.yn.sample.CheckAndSet();  其descriptor为：()V
     * 对于方法：  public void checkAndSetF(int);   其descriptor为：(I)V
     * (I)V表示：I表示参数为int，V表示返回为void
     */
    METHOD_INFO_DESCRIPTOR_STARTED(25,"方法的描述符"),

    /**
     * 方法的权限标记,对于方法：
     *   public void checkAndSetF1(int);
     *   其 flags为：ACC_PUBLIC
     */
    METHOD_INFO_FLAGS_STARTED(30,"方法的权限标记"),

    /**
     * 方法的堆栈、本地变量表等的大小信息
     * 如：
     *       stack=1, locals=4, args_size=2
     */
    METHOD_INFO_STACK_SIZE_LOCAL_VARIABLES_SIZE_STARTED(35,"方法的堆栈、本地变量表等的大小信息"),

    /**
     * 要解析的javap method code部分如下：
     * Code:
     *       stack=1, locals=1, args_size=1
     *          0: aload_0
     *          1: invokespecial #1                  // Method java/lang/Object."<init>":()V
     *          4: return
     *
     * 所以，前一个状态为：{@link #METHOD_INFO_STACK_SIZE_LOCAL_VARIABLES_SIZE_STARTED}
     * 前一个状态处理完了stack=1, locals=4, args_size=2后，就会切换状态为本状态。
     * 开始解析方法的指令集合
     */
    METHOD_CODE_INSTRUCTION_STARTED(40,"开始解析方法的指令集合"),

    METHOD_CODE_END(45,"方法的代码区域解析结束"),
    METHOD_INFO_END(50,"一个方法解析完成"),
    ;
    public int state;

    public String desc;

    ParseStateEnum(int state, String desc) {
        this.state = state;
        this.desc = desc;
    }
}
